"""
模块名称: example_tcpserver.py
作者: Lysander.Li
创建时间: 2025 - 11 - 05
最后修改时间: 2025 - 11 - 05
功能描述: TCP服务端示例程序
"""

import usocket
import _thread
import utime
import log

class TCPServer:
    """TCP服务器类
    参数：
    address - 服务器地址
    port - 服务器端口
    功能：
    - 创建TCP服务器，监听指定地址和端口
    - 支持多客户端并发连接
    - 接收客户端发送的数据，并返回给客户端（回显）
"""
    def __init__(self, address, port):
        self.address = address
        self.port = port
        self.sock = None
        self.is_running = False
        self.logger = log.getLogger("TCP_SERVER")
    
    def start(self):
        """启动TCP服务器"""
        try:
            # 创建socket对象
            self.sock = usocket.socket(usocket.AF_INET, usocket.SOCK_STREAM, usocket.IPPROTO_TCP_SER)
            self.logger.info('socket object created.')
            
            # 绑定地址和端口
            self.sock.bind((self.address, self.port))
            self.logger.info('bind address: {}, port: {}'.format(self.address, self.port))

            # 监听连接请求
            self.sock.listen(10)
            self.logger.info('started, listening ...')

            self.is_running = True
            
            # 开始接受连接
            while self.is_running:
                try:
                    # 接受客户端连接
                    cli_conn, cli_ip_addr, cli_port = self.sock.accept()
                    self.logger.info('accept a client: {}, {}'.format(cli_ip_addr, cli_port))
                    
                    # 为每个客户端连接创建新线程
                    _thread.start_new_thread(self._client_conn_proc, (cli_conn, cli_ip_addr, cli_port))
                except Exception as e:
                    if self.is_running:
                        self.logger.error('Error accepting connection: {}'.format(e))
                    break
        except Exception as e:
            self.logger.error('Failed to start server: {}'.format(e))
            self.stop()
    
    def stop(self):
        """停止TCP服务器"""
        self.is_running = False
        if self.sock:
            self.sock.close()
            self.sock = None
            self.logger.info('server stopped.')
    
    def _client_conn_proc(self, conn, ip_addr, port):
        """处理客户端连接的内部方法
            功能：
            - 接收客户端发送的数据
            - 将接收到的数据发送回客户端（回显）
        """
        try:
            while True:
                # 接收客户端发送的数据
                data = conn.recv(1024)
                if not data:
                    # 客户端断开连接
                    break

                self.logger.info('[client addr: {}, {}] recv data: {}'.format(ip_addr, port, data))
                
                # 将数据发送回客户端
                conn.send(data)
        except Exception as e:
            self.logger.error('[client addr: {}, {}] error: {}'.format(ip_addr, port, e))
        finally:
            # 连接异常，关闭连接
            self.logger.info('[client addr: {}, {}] disconnected'.format(ip_addr, port))
            conn.close()


from usr.example_tcpclient import TCPClient

def client_run(server_addr, server_port):
    """客户端运行"""
    # 创建并使用TCP客户端
    client = TCPClient(server_addr, server_port)
    client.connect()

    while True:
        # 发送消息
        bytes_sent = client.send('my name is QuecPython\r\n')
        client.logger.info('send {} bytes'.format(bytes_sent))
        
        # 接收响应
        data = client.recv(256)
        client.logger.info('recv: {}'.format(data.decode()))

        utime.sleep(10)
        
    
# 主程序
if __name__ == '__main__':
    import dataCall

    log.basicConfig(level=log.INFO)
           
    # 获取模块IP地址
    server_addr = dataCall.getInfo(1, 0)[2][2]
    server_port = 80
    
    # 创建服务器实例
    server = TCPServer(server_addr, server_port)
    
    # 在新线程中启动服务器
    _thread.start_new_thread(server.start, ())
    
    # 确保服务器成功启动
    server.logger.info('sleep 3s to ensure that the server starts successfully.')
    utime.sleep(3)
    
    # 创建客户端实例并运行
    try:
        print('[client] start ...')
        client_run(server_addr, server_port)
    except KeyboardInterrupt:
        server.stop()
        print('[client] stop.')

    
